#!/usr/bin/env python

#    Copyright (c) 2007, Corey Goldberg (corey@goldb.org)
#
#    This file is part of PerfLog.
#
#    PerfLog is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.


from weblog import WebLog
from timeseries import TimeSeries
from grapher import bar_graph
from report import Report
import corestats
import time
import os
import sys

# Optimization:
#   You can get a significant boost in processing speed by 
#   using the Psyco extension module (JIT compiler).  Psyco
#   emits machine code on the fly instead of interpreting your 
#   Python program step by step.
#   See http://psyco.sourceforge.net/
#   This program will run with or without Psyco installed.
try:
    import psyco
    psyco.full()
except:
    pass


if len(sys.argv) != 2:
    print 'usage: perflog.py <logfile>\n'
    raw_input("press ENTER to exit...")
    sys.exit(1)
else:
    log_name = sys.argv[1]
    out_dir = ('results_%s_%s' % (time.strftime('%m.%d.%Y_%H.%M.%S', time.localtime()), log_name))




def main():
    os.mkdir(out_dir)
    log = WebLog(log_name)
    ts = TimeSeries([(parts[len(parts) - 1], '') for parts in log.line_parts], 1)
    stats = corestats.Stats(ts.counts)
    report = Report('%s/%s' % (out_dir, 'report.html'))
    
    report.writeln('<h1>Web Log - Analysis Report</h1>')
    
    report.writeln('<hr />')
    
    report.writeln('log_name: %s <br />' % log_name)
    report.writeln('num requests: %s <br />' % log.num_requests)
    report.writeln('duration: %s secs <br />' % ts.timespan)
    report.writeln('date_time start: %s <br />' % ts.date_time_start)
    report.writeln('date_time finish: %s <br />' % ts.date_time_finish)
    
    report.writeln('<hr />')
    
    report.writeln('<img src="content_types.png" alt="content_types.png"></img>')
    bar_graph(log.content_types, 'Content Types', out_dir + '/content_types.png')
    
    report.writeln('<img src="http_methods.png" alt="http_methods.png"></img>')
    bar_graph(log.methods, 'HTTP Methods', out_dir + '/http_methods.png')
    
    report.writeln('<img src="status_codes.png" alt="status_codes.png"></img>')
    bar_graph(log.status_codes, 'HTTP Status Codes', out_dir + '/status_codes.png')
    
    report.writeln('<hr />')
    
    report.writeln('<h2>Throughput Stats (requests/sec)</h2>')
    report.writeln('avg: %.2f <br />' % stats.avg())
    report.writeln('stdev: %.2f <br />' % stats.stdev())
    report.writeln('min: %.2f <br />' % stats.min())
    report.writeln('pct80: %.2f <br />' % stats.percentile(80))
    report.writeln('pct90: %.2f <br />' % stats.percentile(90))
    report.writeln('pct95: %.2f <br />' % stats.percentile(95))
    report.writeln('pct99: %.2f <br />' % stats.percentile(99))
    report.writeln('max: %.2f <br />' % stats.max())
    
    report.writeln('<hr />')
    
    report.writeln('<img src="req_sec.png" alt="req_sec.png"></img>')
    graph_throughput(log, 1, 'Requests/Sec', 'req_sec.png')
    
    report.writeln('<img src="req_min.png" alt="req_min.png"></img>')
    graph_throughput(log, 60, 'Requests/Min', 'req_min.png')
    
    report.writeln('<img src="req_hour.png" alt="req_hour.png"></img>')
    graph_throughput(log, 3600, 'Requests/Hour', 'req_hour.png')
    
    report.writeln('<hr />')
    
    report.close()
    



def graph_throughput(log, interval, title, img_name):
    ts = TimeSeries([(parts[len(parts) - 1], '') for parts in log.line_parts], interval)    
    througput_per_interval = {}
    for i in range(len(ts.counts)):
        througput_per_interval[i] = ts.counts[i]
    bar_graph(througput_per_interval, title, output_name='%s/%s' % (out_dir, img_name), xlabels=False)    
    
    
    
    
if __name__ == "__main__":
    print 'processing...'
    start = time.time()
    main()
    finish = time.time()
    print '\nDONE  runtime: %.2f secs' % (finish - start)
